/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-17     hehung       the first version
 */

/*
 * Use the packages ssd1306
 * */

#include "app_oled.h"
#include "bmp.h"
#include "board.h"
#include "ssd1306.h"
#include "app_rtc.h"
#include <stdio.h>
#include "app_key.h"
#include "codetab.h"
#include "app_config.h"
#include "app_esp8266.h"

#if 0
#define ESP8266_OLED_DEBUG
#endif
#if 0
#define ESP8266_OLED_ESP8266_INIT_DEBUG
#endif

#define OLED_DATA_RECV_WAIT_CLEAR            ((uint16_t)0u)
#define OLED_DATA_RECV_WAIT_START            ((uint16_t)1u)
#define OLED_DATA_RECV_WAIT_TIMEOUT          ((uint16_t)100u)    /*0.5*10s = 50s*/

#ifndef ESP8266_OLED_ESP8266_INIT_DEBUG
static uint8_t OLED_ShowTabFlg = OLED_DISPLAY_ESP8266_INIT;
#else
static uint8_t OLED_ShowTabFlg = OLED_DISPLAY_TIME;
#endif
static uint8_t OLED_LastShowTabFlg = OLED_DISPLAY_TIME;
static uint16_t OLED_ShowSlice = 300u;
static uint16_t s_key_press_cnt = 0u;    /*switch hold counter*/
static uint16_t s_data_recv_wait_cnt = 0u;
static uint8_t OLED_MessageWarningFlag = 0u;
static uint8_t OLED_key_switch_pressed_flag[3] = {0};
static uint8_t OLED_key_switch_released_flag[3] = {0};
static uint8_t OLED_msg_tips_flag = 0u;
/*Date-time setting*/
static uint8_t Month_day_num[12] = {31,28,31,20,31,30,31,31,30,31,30,31};
static rtc_date setting_date;
static uint8_t  setting_index = 0;
/*Wifi retry*/
static uint8_t  wifi_retry_flag = 0u;
/*Get Time*/
static uint8_t  intnet_time_get_flag = 0u;


static void OLED_ManageEntry(void *parameter);
static void OLED_ThreadManage(void);
static void OLED_DrawBmpImg(uint8_t x,
                            uint8_t y,
                            SSD1306_COLOR color,
                            const uint8_t bmp[][16],
                            uint32_t len);
static void OLED_DrawBmpImg2(uint8_t x,
                            uint8_t y,
                            SSD1306_COLOR color,
                            const uint8_t bmp[][8],
                            uint32_t len,
                            uint8_t size);
static void OLED_Hz_String(uint8_t x,
                           uint8_t y,
                           uint8_t chr_S,
                           uint8_t chr_E,
                           SSD1306_COLOR color);
static void OLED_DrawHz(uint8_t x,
                        uint8_t y,
                        uint8_t chr,
                        SSD1306_COLOR color);
static void OLED_ShowTime(void);
static void OLED_ShowSetting(void);
static void OLED_ShowWifiSetting(void);
static void OLED_ShowTimeSetting(void);
static void OLED_ShowDataDownload(void);
static void OLED_ShowMsgIco(void);
static void OLED_DataDownloadCnt(void);
static void OLED_ShowWifiInit(void);
static void OLED_SwitchLogic(void);
static void OLED_ShowDateSetting(void);
static void OLED_LoadCurrentDate(void);
static void OLED_DateSettingIncrese(void);
static void OLED_DateSettingDecrease(void);
static uint8_t OLED_JudgeLeapYear(int16_t paraYear);
static void OLED_ShowWifiRetry(void);
static void OLED_ShowDateTimeRetry(void);

/*
 * System startup display
 * */
void OLED_AppInit(void)
{
    OLED_ThreadManage();
}

void OLED_SetDisplayFlag(uint8_t paraFlg)
{
    OLED_ShowTabFlg = paraFlg;
}

uint8_t OELD_GetMsgWarningFlg(void)
{
    return OLED_MessageWarningFlag;
}

void OLED_SetMsgTipsFlag(uint8_t paraFlg)
{
    OLED_msg_tips_flag = paraFlg;
}

uint8_t OLED_GetWifiRetryStatus(void)
{
    return wifi_retry_flag;
}

void OLED_ClrWifiRetryStatus(void)
{
    wifi_retry_flag = 0u;
}

uint8_t OLED_GetDateTimeRetryStatus(void)
{
    return intnet_time_get_flag;
}

void OLED_ClrDateTimeRetryStatus(void)
{
    intnet_time_get_flag = 0u;
}

/**/
static void OLED_ManageEntry(void *parameter)
{
    ssd1306_Init();    /*IIC and OLED initial*/

#if (APP_OLED_DEBUG == APP_CONF_ON)
    ssd1306_Fill(Black);
    OLED_DrawBmpImg(0, 0, Black, RTT_logo, Get_Rtt_logo_len());
    ssd1306_UpdateScreen();
    rt_thread_mdelay(OLED_ShowSlice);

    ssd1306_Fill(Black);
    OLED_DrawBmpImg(0, 18, White, AB_logo, Get_AB_logo_len());
    ssd1306_UpdateScreen();
    rt_thread_mdelay(OLED_ShowSlice);

    ssd1306_Fill(Black);
    OLED_DrawBmpImg(0, 10, White, EleFans_logo, Get_EleFans_logo_len());
    ssd1306_UpdateScreen();
    rt_thread_mdelay(OLED_ShowSlice);

    ssd1306_Fill(Black);
    OLED_DrawBmpImg(0, 10, White, my_logo, Get_my_logo_len());
    ssd1306_UpdateScreen();
    rt_thread_mdelay(OLED_ShowSlice);
#endif

#ifndef ESP8266_OLED_ESP8266_INIT_DEBUG
    OLED_ShowWifiInit();
    ESP8266_SysInit();
#endif
    while(1)
    {
        OLED_SwitchLogic();    /*Switch changed*/

        switch(OLED_ShowTabFlg)
        {
            case OLED_DISPLAY_NONE:
            {
                if(OLED_ShowTabFlg != OLED_LastShowTabFlg)
                {
                    s_data_recv_wait_cnt = OLED_DATA_RECV_WAIT_START;
//                    rt_kprintf("Receiving Data\n");
                    OLED_ShowDataDownload();
                    OLED_ShowSlice = 500u;
                }
                else
                {
                    OLED_DataDownloadCnt();
                }
            } break;
            case OLED_DISPLAY_TIME:
            {
                OLED_ShowTime();
                OLED_ShowSlice = 50u;
            } break;
            case OLED_DISPLAY_SETTING:
            {
                if(OLED_ShowTabFlg != OLED_LastShowTabFlg)
                {
                    OLED_ShowSetting();
                    OLED_ShowSlice = 200u;
                }
            } break;
            case OLED_DISPLAY_WIFI:
            {
                if(OLED_ShowTabFlg != OLED_LastShowTabFlg)
                {
                    OLED_ShowWifiSetting();
                    OLED_ShowSlice = 200u;
                }
            } break;
            case OLED_DISPLAY_CLOCK:
            {
                if(OLED_ShowTabFlg != OLED_LastShowTabFlg)
                {
                    OLED_ShowTimeSetting();
                    OLED_ShowSlice = 200u;
                }

            } break;
            case OLED_DISPLAY_MSG:
            {
                if(OLED_ShowTabFlg != OLED_LastShowTabFlg)
                {
                    OLED_ShowMsgIco();
                    OLED_ShowSlice = 200u;
                }
            } break;
            case OLED_DISPLAY_MSG_RECIVED:
            {
                OLED_ShowImgFromESP8266Server(ESP8266_GetRecvMsgData(), White);
            } break;
            case OLED_DISPLAY_ESP8266_INIT:
            {
                /*Do Nothing for Initialize ESP8266 module in app_esp8266.c*/
            } break;
            case OLED_DISPLAY_RECV_FINISH:
            {
                OLED_ShowSlice = 200u;
            } break;
            case OLED_DISPLAY_DATE_SETTING:
            {
                if(OLED_ShowTabFlg != OLED_LastShowTabFlg)
                {
                    OLED_LoadCurrentDate();
                }
                OLED_ShowDateSetting();
                OLED_ShowSlice = 100u;
            } break;
            case OLED_DISPLAY_WIFI_RETRY:
            {
                if(wifi_retry_flag == 0u)
                {
                    OLED_ShowWifiRetry();
                }
                OLED_ShowSlice = 200u;
            } break;
            case OLED_DISPLAY_INTNETTIME:
            {
                if(intnet_time_get_flag == 0)
                {
                    OLED_ShowDateTimeRetry();
                }
                OLED_ShowSlice = 200u;
            } break;
        }

        OLED_LastShowTabFlg = OLED_ShowTabFlg;
        rt_thread_mdelay(OLED_ShowSlice);
    }
}

void OLED_SwitchPressed(uint8_t paraKeyNum)
{
    OLED_key_switch_pressed_flag[paraKeyNum] = 1u;
}

void OLED_SwitchReleased(uint8_t paraKeyNum)
{
    OLED_key_switch_released_flag[paraKeyNum] = 1u;
}

static void OLED_SwitchLogic(void)
{
    /*Switch pressed logic*/
    if(OLED_key_switch_pressed_flag[0] == 1u)
    {
        OLED_key_switch_pressed_flag[0] = 0u;
        OLED_Display2RightSwitch();
    }
    else if(OLED_key_switch_pressed_flag[1] == 1u)
    {
        OLED_key_switch_pressed_flag[1] = 0u;
        OLED_Display2LeftSwitch();
    }
    else if(OLED_key_switch_pressed_flag[2] == 1u)
    {
        OLED_key_switch_pressed_flag[2] = 0u;
    }

    /*Switch Released logic*/
    if(OLED_key_switch_released_flag[0] == 1u)
    {
        OLED_key_switch_released_flag[0] = 0u;
    }
    else if(OLED_key_switch_released_flag[1] == 1u)
    {
        OLED_key_switch_released_flag[1] = 0u;
    }
    else if(OLED_key_switch_released_flag[2] == 1u)
    {
        OLED_key_switch_released_flag[2] = 0u;
        OLED_DisplayThreeSwitch();
    }
}

void OLED_Display2RightSwitch(void)
{
    switch(OLED_ShowTabFlg)
    {
        case OLED_DISPLAY_TIME:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_SETTING;
        } break;
        case OLED_DISPLAY_SETTING:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_WIFI;
        } break;
        case OLED_DISPLAY_WIFI:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_CLOCK;
        } break;
        case OLED_DISPLAY_CLOCK:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_MSG;
        } break;
        case OLED_DISPLAY_MSG:
        {

        } break;
        case OLED_DISPLAY_DATE_SETTING:
        {
            OLED_DateSettingIncrese();
        } break;
    }
}

void OLED_Display2LeftSwitch(void)
{
    switch(OLED_ShowTabFlg)
    {
        case OLED_DISPLAY_TIME:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_MSG;
        } break;
        case OLED_DISPLAY_SETTING:
        {

        } break;
        case OLED_DISPLAY_WIFI:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_SETTING;
        } break;
        case OLED_DISPLAY_CLOCK:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_WIFI;
        } break;
        case OLED_DISPLAY_MSG:
        {
            OLED_ShowTabFlg = OLED_DISPLAY_CLOCK;
        } break;
        case OLED_DISPLAY_DATE_SETTING:
        {
            OLED_DateSettingDecrease();
        } break;
    }
}

void OLED_DisplayTressSwitchHoldCnt(void)
{
    s_key_press_cnt = (s_key_press_cnt > KEY_HOLD_LONG_TIME) ?
                      (KEY_HOLD_LONG_TIME) : (++s_key_press_cnt);
//    rt_kprintf("%d--", s_key_press_cnt);
}

void OLED_DisplayThreeSwitch(void)
{
    /*短按，<=500ms*/
    if(s_key_press_cnt <= (uint16_t)(KEY_HOLD_SHORT_TIME/KEY_SAMPLE_PERIOD))
    {
        switch(OLED_ShowTabFlg)
        {
            case OLED_DISPLAY_TIME: OLED_ShowTabFlg = OLED_DISPLAY_MSG_RECIVED;break;
            case OLED_DISPLAY_SETTING:
            case OLED_DISPLAY_WIFI:
            case OLED_DISPLAY_CLOCK:
            case OLED_DISPLAY_MSG:
            case OLED_DISPLAY_ESP8266_INIT:
            case OLED_DISPLAY_RECV_FINISH:
            {
                /*Exit to display the time*/
                OLED_ShowTabFlg = OLED_DISPLAY_TIME;
            } break;
            case OLED_DISPLAY_MSG_RECIVED:
            {
                OLED_msg_tips_flag = 0u;
                OLED_ShowTabFlg = OLED_DISPLAY_MSG; break;
            } break;
            case OLED_DISPLAY_DATE_SETTING:
            {
                /*设置时间*/
                RTC_DateUpdate(setting_date);
                OLED_ShowTabFlg = OLED_DISPLAY_SETTING; break;
            } break;
            case OLED_DISPLAY_WIFI_RETRY:
            {
                OLED_ShowTabFlg = OLED_DISPLAY_WIFI;
            } break;
            case OLED_DISPLAY_INTNETTIME:
            {
                OLED_ShowTabFlg = OLED_DISPLAY_CLOCK;
            } break;
        }
    }
    else    /*长按>500ms*/
    {
        switch(OLED_ShowTabFlg)
        {
            case OLED_DISPLAY_TIME:    OLED_ShowTabFlg = OLED_DISPLAY_MSG_RECIVED;break;
            case OLED_DISPLAY_SETTING: OLED_ShowTabFlg = OLED_DISPLAY_DATE_SETTING;break;
            case OLED_DISPLAY_WIFI:    OLED_ShowTabFlg = OLED_DISPLAY_WIFI_RETRY;break;
            case OLED_DISPLAY_CLOCK:   OLED_ShowTabFlg = OLED_DISPLAY_INTNETTIME;break;
            case OLED_DISPLAY_MSG:     OLED_ShowTabFlg = OLED_DISPLAY_MSG_RECIVED;break;
            case OLED_DISPLAY_DATE_SETTING:
            {
                setting_index = (setting_index >= 5) ? (0):(++setting_index);
            } break;
            case OLED_DISPLAY_WIFI_RETRY:
            {
                wifi_retry_flag = 1u;
                ESP8266_SysRetey();
                OLED_Hz_String(23, 48, 42, 43, White);
                OLED_Hz_String(23+16*2, 48, 40, 41, White);
                OLED_Hz_String(23+16*4, 48, 44, 44, White);
                ssd1306_UpdateScreen();
            } break;
            case OLED_DISPLAY_INTNETTIME:
            {
                intnet_time_get_flag = 1u;
                ESP8266_SysDateTimeRetey();
                OLED_Hz_String(23, 48, 36, 37, White);
                OLED_Hz_String(23+16*2, 48, 32, 33, White);
                OLED_Hz_String(23+16*4, 48, 44, 44, White);
                ssd1306_UpdateScreen();
            } break;
        }
    }
//    else if(s_key_press_cnt < (uint16_t)(KEY_HOLD_MIDDLE_TIME/KEY_SAMPLE_PERIOD))
//    {
//
//    }
//    else if(s_key_press_cnt >= (uint16_t)(KEY_HOLD_LONG_TIME/KEY_SAMPLE_PERIOD))
//    {
//
//    }

    s_key_press_cnt = 0u;
}

static void OLED_ShowSetting(void)
{
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(24, 8, White, Setting_48X48, Get_Setting_48X48_len(), 48);
    OLED_DrawHz(88, 12, 4, White);    /*设*/
    OLED_DrawHz(88, 36, 5, White);    /*置*/
    OLED_DrawHz(112, 24, 0, White);   /*>*/
    ssd1306_UpdateScreen();
}

static void OLED_ShowWifiSetting(void)
{
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(24, 8, White, Wifi_48X48, Get_Wifi_48X48_len(), 48);
    OLED_DrawHz(88, 12, 8, White);    /*无*/
    OLED_DrawHz(88, 36, 9, White);    /*线*/
    OLED_DrawHz(112, 24, 0, White);   /*>*/
    OLED_DrawHz(0, 24, 3, White);     /*<*/
    ssd1306_UpdateScreen();
}

static void OLED_ShowTimeSetting(void)
{
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(24, 8, White, Clock_48X48, Get_Clock_48X48_len(), 48);
    OLED_DrawHz(88, 12, 6, White);    /*时*/
    OLED_DrawHz(88, 36, 7, White);    /*钟*/
    OLED_DrawHz(112, 24, 0, White);   /*>*/
    OLED_DrawHz(0, 24, 3, White);     /*<*/
    ssd1306_UpdateScreen();
}

static void OLED_ShowMsgIco(void)
{
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(24, 8, White, Message_48X48, Get_Message_48X48_len(), 48);
    OLED_DrawHz(88, 12, 30, White);    /*信*/
    OLED_DrawHz(88, 36, 31, White);    /*息*/
    OLED_DrawHz(0, 24, 3, White);     /*<*/
    ssd1306_UpdateScreen();
}

static void OLED_ShowWifiRetry(void)
{
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(0, 0, White, Wifi_24X24, Get_Wifi_24X24_len(), 24);
    OLED_Hz_String(23, 0, 38, 43, White);
    OLED_Hz_String(48, 28, 47, 48, Black);
    ssd1306_UpdateScreen();
}

static void OLED_ShowDateTimeRetry(void)
{
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(0, 0, White, Clock_24X24, Get_Clock_24X24_len(), 24);
    OLED_Hz_String(23, 0, 32, 37, White);
    OLED_Hz_String(48, 28, 47, 48, Black);
    ssd1306_UpdateScreen();
}

static void OLED_LoadCurrentDate(void)
{
    struct tm *currentDateTime;

    currentDateTime = RTC_GetTime();

    setting_date.m_year = currentDateTime->tm_year+1900u;
    setting_date.m_month = currentDateTime->tm_mon+1u;
    setting_date.m_day = currentDateTime->tm_mday;
    setting_date.m_hour = currentDateTime->tm_hour;
    setting_date.m_min = currentDateTime->tm_min;
    setting_date.m_sec = currentDateTime->tm_sec;
}

static void OLED_ShowDateSetting(void)
{
    char str_date_year[4];
    char str_date_mon[2];
    char str_date_day[2];
    char str_time_hour[2];
    char str_time_min[2];
    char str_time_sec[2];

    /*Time-date setting*/
    ssd1306_Fill(Black);
    OLED_DrawBmpImg2(0, 0, White, Setting_24X24, Get_Setting_24X24_len(), 24);
    OLED_Hz_String(48, 0, 36, 37, White);
    sprintf(str_date_year, "%04d", setting_date.m_year);
    sprintf(str_date_mon , "%02d", setting_date.m_month);
    sprintf(str_date_day , "%02d", setting_date.m_day);
    sprintf(str_time_hour, "%02d", setting_date.m_hour);
    sprintf(str_time_min , "%02d", setting_date.m_min);
    sprintf(str_time_sec , "%02d", setting_date.m_sec);

    ssd1306_SetCursor(20, 20);
    ssd1306_WriteString(str_time_hour, Font_11x18, (setting_index==0)?(Black):(White));
    ssd1306_SetCursor(42, 20);
    ssd1306_WriteString(":", Font_11x18, White);
    ssd1306_SetCursor(53, 20);
    ssd1306_WriteString(str_time_min , Font_11x18, (setting_index==1)?(Black):(White));
    ssd1306_SetCursor(75, 20);
    ssd1306_WriteString(":", Font_11x18, White);
    ssd1306_SetCursor(86, 20);
    ssd1306_WriteString(str_time_sec , Font_11x18, (setting_index==2)?(Black):(White));

    ssd1306_SetCursor(9, 42);
    ssd1306_WriteString(str_date_year, Font_11x18, (setting_index==3)?(Black):(White));
    ssd1306_SetCursor(53, 42);
    ssd1306_WriteString("-", Font_11x18, White);
    ssd1306_SetCursor(64, 42);
    ssd1306_WriteString(str_date_mon , Font_11x18, (setting_index==4)?(Black):(White));
    ssd1306_SetCursor(86, 42);
    ssd1306_WriteString("-", Font_11x18, White);
    ssd1306_SetCursor(97, 42);
    ssd1306_WriteString(str_date_day , Font_11x18, (setting_index==5)?(Black):(White));

    ssd1306_UpdateScreen();
}

static uint8_t OLED_JudgeLeapYear(int16_t paraYear)
{
    if(paraYear%400 == 0)
    {
        return 1;
    }
    else
    {
        if((paraYear%4 == 0) && (paraYear%100 != 0))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

static void OLED_DateSettingIncrese(void)
{
/*    rt_kprintf("---->%d,%d,%d,%d,%d,%d\n", setting_date.m_year,
                                           setting_date.m_month,
                                           setting_date.m_day,
                                           setting_date.m_hour,
                                           setting_date.m_min,
                                           setting_date.m_sec);*/
    switch(setting_index)
    {
        case 0: setting_date.m_hour =(setting_date.m_hour >= 23)  ?(0):(++setting_date.m_hour);break;    /*Hour*/
        case 1: setting_date.m_min  =(setting_date.m_min  >= 59)  ?(0):(++setting_date.m_min);break;    /*Min*/
        case 2: setting_date.m_sec  =(setting_date.m_sec  >= 59)  ?(0):(++setting_date.m_sec);break;    /*Sec*/
        case 3: setting_date.m_year =(setting_date.m_year >= 9999)?(0):(++setting_date.m_year);break;    /*Year*/
        case 4: setting_date.m_month=(setting_date.m_month>= 12)  ?(1):(++setting_date.m_month);break;    /*Month*/
        case 5:
            /*Leap year and February*/
            if((OLED_JudgeLeapYear(setting_date.m_year) == 1) && (setting_date.m_month == 2))
            {
                Month_day_num[1] = 29;    /*February in leap year is 29 days*/
            }
            setting_date.m_day  =(setting_date.m_day  >= Month_day_num[setting_date.m_month-1])?(1):(++setting_date.m_day);
            break;    /*Day*/
    }
}

static void OLED_DateSettingDecrease(void)
{
    switch(setting_index)
    {
    case 0: setting_date.m_hour =(setting_date.m_hour <= 0)?(23)  :(--setting_date.m_hour);break;    /*Hour*/
    case 1: setting_date.m_min  =(setting_date.m_min  <= 0)?(59)  :(--setting_date.m_min);break;    /*Min*/
    case 2: setting_date.m_sec  =(setting_date.m_sec  <= 0)?(59)  :(--setting_date.m_sec);break;    /*Sec*/
    case 3: setting_date.m_year =(setting_date.m_year <= 0)?(9999):(--setting_date.m_year);break;    /*Year*/
    case 4: setting_date.m_month=(setting_date.m_month<= 1)?(12)  :(--setting_date.m_month);break;    /*Month*/
    case 5:
        /*Leap year and February*/
        if((OLED_JudgeLeapYear(setting_date.m_year) == 1) && (setting_date.m_month == 2))
        {
            Month_day_num[1] = 29;    /*February in leap year is 29 days*/
        }
        setting_date.m_day  =(setting_date.m_day <= 1)?(Month_day_num[setting_date.m_month-1]):(--setting_date.m_day);
        break;    /*Day*/
    }
}

static void OLED_ShowTime(void)
{
    char timeStr[8u] = {0};
    char dateMonStr[2u] = {0};
    char dateDayStr[2u] = {0};
    struct tm *currentDateTime;
    static uint8_t Last_sec = 0u;

    currentDateTime = RTC_GetTime();

    /*If Time is changed, Update it*/
    if(Last_sec != currentDateTime->tm_sec)
    {
        ssd1306_Fill(Black);
        ssd1306_SetCursor(0, 18);   /*Time*/
        sprintf(timeStr, (const char *)"%02d:%02d:%02d", currentDateTime->tm_hour,\
                                     currentDateTime->tm_min,\
                                     currentDateTime->tm_sec);
        ssd1306_WriteString(timeStr, Font_16x26, White);

        ssd1306_SetCursor(0, 46);    /*Date*/
        sprintf(dateMonStr, (const char *)"%02d", (currentDateTime->tm_mon+1u));
        ssd1306_WriteString(dateMonStr, Font_11x18, White);
        OLED_DrawHz(22, 46, 19, White);    /*月*/
        ssd1306_SetCursor(38, 46);    /*Date*/
        sprintf(dateDayStr, (const char *)"%02d", currentDateTime->tm_mday);
        ssd1306_WriteString(dateDayStr, Font_11x18, White);
        OLED_DrawHz(60, 46, 20, White);    /*日*/

        OLED_DrawHz(80, 46, 21, White);    /*星期*/
        OLED_DrawHz(96, 46, 22, White);    /*星期*/
        switch(currentDateTime->tm_wday)
        {
            case 1: OLED_DrawHz(112, 46, 23, White);break;    /*一*/
            case 2: OLED_DrawHz(112, 46, 24, White);break;    /*二*/
            case 3: OLED_DrawHz(112, 46, 25, White);break;    /*三*/
            case 4: OLED_DrawHz(112, 46, 26, White);break;    /*四*/
            case 5: OLED_DrawHz(112, 46, 27, White);break;    /*五*/
            case 6: OLED_DrawHz(112, 46, 28, White);break;    /*六*/
            case 0: OLED_DrawHz(112, 46, 29, White);break;    /*日*/
        }

        if(ESP8266_GetInitSuccFlg())
        {
            OLED_DrawBmpImg2(5, 0, White, Wifi_16X16, Get_Wifi_16X16_len(), 16);
        }

        if(1u == OLED_msg_tips_flag)
        {
            OLED_DrawBmpImg2(107, 0, White, Message_16X16, Get_Message_16X16_len(), 16);
        }
    }

    ssd1306_UpdateScreen();

    Last_sec = currentDateTime->tm_sec;
}

static void OLED_ShowDataDownload(void)
{
    ssd1306_Fill(Black);
    ssd1306_SetCursor(92, 24);
    OLED_Hz_String(12, 24, 10, 14, White);
    ssd1306_WriteString("...", Font_7x10, White);
    ssd1306_UpdateScreen();
}

static void OLED_ShowWifiInit(void)
{
    ssd1306_Fill(Black);
    ssd1306_SetCursor(18, 24);
    ssd1306_WriteString("Wifi", Font_11x18, White);
    OLED_Hz_String(64, 24, 15, 17, White);
    ssd1306_UpdateScreen();
}

void OLED_ShowImgFromESP8266Server(const uint8_t *paraImg, uint8_t color)
{
    uint16_t i = 0u;
    uint8_t j = 0u;
    uint8_t x=0u, y=0u;
    uint8_t tmp = 0;

    ssd1306_Fill(Black);    /*Clear*/
    for(i=0; i<OLED_ESP8266_RECV_IMG_NUM; i++)
    {
        //rt_kprintf("%x", paraImg[i]);
        tmp = (White == color) ? (paraImg[i]):(~paraImg[i]);
        if((i%32 == 0u) && (i != 0u))
        {
            x = 0u;
            y++;
            //rt_kprintf("\n");
        }

        for(j=0; j<4; j++)    /*half of a byte*/
        {
            if(tmp&0x08)
                ssd1306_DrawPixel(x, y, White);
            tmp <<= 1u;
            x++;
        }
    }
    ssd1306_UpdateScreen();
}

static void OLED_DataDownloadCnt(void)
{
    if(s_data_recv_wait_cnt != OLED_DATA_RECV_WAIT_CLEAR)
    {
        if(s_data_recv_wait_cnt < OLED_DATA_RECV_WAIT_TIMEOUT)
        {
            s_data_recv_wait_cnt ++;
        }
        else
        {
            /*Timeout*/
            OLED_ShowTabFlg = OLED_DISPLAY_TIME;
        }
    }
}

void OLED_DataDownloadRefresh(void)
{
    s_data_recv_wait_cnt = OLED_DATA_RECV_WAIT_START;
}

static void OLED_ThreadManage(void)
{
    rt_thread_t oled_thread;

    oled_thread = rt_thread_create("OLED Thread Manage",     /*线程名字*/
                                   OLED_ManageEntry,         /*线程入口函数*/
                                   RT_NULL,                  /*线程入口函数参数*/
                                   4096,                     /*线程栈大小*/
                                   8,                        /*线程优先级*/
                                   10);                      /*线程时间片*/

    if(oled_thread != RT_NULL)
    {
        rt_kprintf("OLED Thread Created Success!\n");
        rt_thread_startup (oled_thread);
    }
    else
    {
        rt_kprintf("OLED Thread Create Failed!\n");
    }
}

/*Display more than one hanzi*/
static void OLED_Hz_String(uint8_t x,
                           uint8_t y,
                           uint8_t chr_S,
                           uint8_t chr_E,
                           SSD1306_COLOR color)
{
    uint8_t i;

    for(i=chr_S; i<=chr_E; i++)
    {
        OLED_DrawHz(x+16*(i-chr_S), y, i, color);
    }
}

/*Display a HanZi*/
static void OLED_DrawHz(uint8_t x,
                        uint8_t y,
                        uint8_t chr,
                        SSD1306_COLOR color)
{
    uint8_t temp,t,t1;
    uint8_t y0=y;
    uint8_t csize=32u;

    chr <<= 1u;

    for(t=0; t<csize; t++)
    {
        if(t == 16u)
            chr += 1;

        temp=(White == color) ? (Hz[chr][t%16]):(~Hz[chr][t%16]);
//        temp=Hz[chr][t];
        for(t1=0;t1<8;t1++)
        {
            if(temp&0x80)
                ssd1306_DrawPixel(x, y, White);

            temp<<=1;
            y++;
            if((y-y0) == 16)
            {
                y=y0;
                x++;
                break;
            }
        }
    }
}

static void OLED_DrawBmpImg(uint8_t x,
                            uint8_t y,
                            SSD1306_COLOR color,
                            const uint8_t bmp[][16],
                            uint32_t len)
{
    uint16_t t,t1;
    uint8_t  y0 = y;
    uint8_t  temp = 0u;
    uint16_t len2 = (uint16_t)(len>>4u);

    for(t=0; t<len; t++)
    {
        temp=(White == color) ?
             (bmp[(uint8_t)(t/16)][(uint8_t)(t%16)]):(~bmp[(uint8_t)(t/16)][(uint8_t)(t%16)]);

        for(t1=0; t1<8; t1++)
        {
            if(temp&0x80)
                ssd1306_DrawPixel(x, y, White);

            temp <<= 1u;
            y++;
            if((y-y0) == len2)
            {
                y = y0;
                x ++;
                break;
            }
        }
    }
}

static void OLED_DrawBmpImg2(uint8_t x,
                             uint8_t y,
                             SSD1306_COLOR color,
                             const uint8_t bmp[][8],
                             uint32_t len,
                             uint8_t size)
{
    uint16_t t, t1;
    uint8_t  y_end;
    uint8_t  temp;
    uint16_t len2 = 0u;

    y_end = y;

    if(size == 24)
        len2 = (uint16_t)(len/3.2);
    else if(size == 16)
        len2 = (uint16_t)(len/2);
    else if(size == 48)
        len2 = (uint16_t)(len/6);
    else if(size == 64)
        len2 = (uint16_t)(len/16);

    for(t=0; t<len; t++)
    {
        temp=(White == color) ?
             (bmp[(uint8_t)(t/8)][(uint8_t)(t%8)]):(~bmp[(uint8_t)(t/8)][(uint8_t)(t%8)]);

        for(t1=0; t1<8; t1++)
        {
            if(temp&0x80)
                ssd1306_DrawPixel(x, y, White);

            temp <<= 1u;
            y++;
            if((y-y_end) == len2)
            {
                y = y_end;
                x ++;
                break;
            }
        }
    }
}

